From: awilliam@xenbuild.aw Date: Thu, 27 Jul 2006 16:00:00 +0000 (-0600) Subject: [IA64] IO ports for driver domains. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15786^2~2 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=e4e6f4d295d5f8dd2f82b2624cdf1d51162a67ac;p=xen.git [IA64] IO ports for driver domains. Map/unmap IO ports. Signed-off-by: Tristan Gingold --- diff --git a/xen/arch/ia64/xen/dom0_ops.c b/xen/arch/ia64/xen/dom0_ops.c index 28f06d90d1..3561668b58 100644 --- a/xen/arch/ia64/xen/dom0_ops.c +++ b/xen/arch/ia64/xen/dom0_ops.c @@ -285,6 +285,7 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) struct domain *d; unsigned int fp = op->u.ioport_permission.first_port; unsigned int np = op->u.ioport_permission.nr_ports; + unsigned int lp = fp + np - 1; ret = -ESRCH; d = find_domain_by_id(op->u.ioport_permission.domain); @@ -295,9 +296,9 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) ret = 0; else { if (op->u.ioport_permission.allow_access) - ret = ioports_permit_access(d, fp, fp + np - 1); + ret = ioports_permit_access(d, fp, lp); else - ret = ioports_deny_access(d, fp, fp + np - 1); + ret = ioports_deny_access(d, fp, lp); } put_domain(d); diff --git a/xen/arch/ia64/xen/dom_fw.c b/xen/arch/ia64/xen/dom_fw.c index ea9c06fd1d..a3f699646b 100644 --- a/xen/arch/ia64/xen/dom_fw.c +++ b/xen/arch/ia64/xen/dom_fw.c @@ -855,15 +855,17 @@ dom_fw_init (struct domain *d, struct ia64_boot_param *bp, char *fw_mem, int fw_ } else { #ifndef CONFIG_XEN_IA64_DOM0_VP /* Dom0 maps legacy mmio in first MB. */ - MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 1); - MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 1); + MAKE_MD(EFI_LOADER_DATA, EFI_MEMORY_WB, 0*MB, 1*MB, 1); + MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, + HYPERCALL_END, maxmem, 1); #endif - /* hypercall patches live here, masquerade as reserved PAL memory */ - MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END, 1); - /* Create a dummy entry for IO ports, so that IO accesses are - trapped by Xen. */ - MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE,EFI_MEMORY_UC, - 0x00000ffffc000000, 0x00000fffffffffff, 1); + /* hypercall patches live here, masquerade as reserved + PAL memory */ + MAKE_MD(EFI_PAL_CODE, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME, + HYPERCALL_START, HYPERCALL_END, 1); + /* Create an entry for IO ports. */ + MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC, + IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE, 1); MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0); } diff --git a/xen/arch/ia64/xen/mm.c b/xen/arch/ia64/xen/mm.c index e541a1660d..5a24f06a8f 100644 --- a/xen/arch/ia64/xen/mm.c +++ b/xen/arch/ia64/xen/mm.c @@ -180,6 +180,8 @@ static void domain_page_flush(struct domain* d, unsigned long mpaddr, unsigned long old_mfn, unsigned long new_mfn); #endif +extern unsigned long ia64_iobase; + static struct domain *dom_xen, *dom_io; // followings are stolen from arch_init_memory() @ xen/arch/x86/mm.c @@ -894,6 +896,60 @@ assign_domain_page(struct domain *d, __assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable); } +int +ioports_permit_access(struct domain *d, unsigned long fp, unsigned long lp) +{ + int ret; + unsigned long off; + unsigned long fp_offset; + unsigned long lp_offset; + + ret = rangeset_add_range(d->arch.ioport_caps, fp, lp); + if (ret != 0) + return ret; + + fp_offset = IO_SPACE_SPARSE_ENCODING(fp) & ~PAGE_MASK; + lp_offset = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp)); + + for (off = fp_offset; off <= lp_offset; off += PAGE_SIZE) + __assign_domain_page(d, IO_PORTS_PADDR + off, + ia64_iobase + off, ASSIGN_nocache); + + return 0; +} + +int +ioports_deny_access(struct domain *d, unsigned long fp, unsigned long lp) +{ + int ret; + struct mm_struct *mm = &d->arch.mm; + unsigned long off; + unsigned long fp_offset; + unsigned long lp_offset; + + ret = rangeset_remove_range(d->arch.ioport_caps, fp, lp); + if (ret != 0) + return ret; + + fp_offset = IO_SPACE_SPARSE_ENCODING(fp) & ~PAGE_MASK; + lp_offset = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp)); + + for (off = fp_offset; off <= lp_offset; off += PAGE_SIZE) { + unsigned long mpaddr = IO_PORTS_PADDR + off; + volatile pte_t *pte; + pte_t old_pte; + + pte = lookup_noalloc_domain_pte_none(d, mpaddr); + BUG_ON(pte == NULL); + BUG_ON(pte_none(*pte)); + + // clear pte + old_pte = ptep_get_and_clear(mm, mpaddr, pte); + } + domain_flush_vtlb_all(); + return 0; +} + #ifdef CONFIG_XEN_IA64_DOM0_VP static void assign_domain_same_page(struct domain *d, diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index 1d1bbf51d8..9546adbc62 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -196,6 +196,10 @@ struct arch_vcpu { #include /* for KERNEL_DS */ #include +/* Guest physical address of IO ports space. */ +#define IO_PORTS_PADDR 0x00000ffffc000000UL +#define IO_PORTS_SIZE 0x0000000004000000UL + #endif /* __ASM_DOMAIN_H__ */ /* diff --git a/xen/include/asm-ia64/iocap.h b/xen/include/asm-ia64/iocap.h index 8ee571bf65..0a0e0215e2 100644 --- a/xen/include/asm-ia64/iocap.h +++ b/xen/include/asm-ia64/iocap.h @@ -7,10 +7,11 @@ #ifndef __IA64_IOCAP_H__ #define __IA64_IOCAP_H__ -#define ioports_permit_access(d, s, e) \ - rangeset_add_range((d)->arch.ioport_caps, s, e) -#define ioports_deny_access(d, s, e) \ - rangeset_remove_range((d)->arch.ioport_caps, s, e) +extern int ioports_permit_access(struct domain *d, + unsigned long s, unsigned long e); +extern int ioports_deny_access(struct domain *d, + unsigned long s, unsigned long e); + #define ioports_access_permitted(d, s, e) \ rangeset_contains_range((d)->arch.ioport_caps, s, e)